package org.dromara.web.appInterface;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.dromara.app.appParams.*;
import org.dromara.app.appReturn.AppDaRenInfo;
import org.dromara.app.appReturn.AppOrderInfo;
import org.dromara.app.appReturn.AppTrendsReturn;
import org.dromara.app.appReturn.AppYueJuPingLunReturn;
import org.dromara.app.cssUtils.CssUtils;
import org.dromara.app.cssUtils.RedisServiceUtils;
import org.dromara.app.domain.SkAppUser;
import org.dromara.app.domain.SkYueDanOrder;
import org.dromara.app.domain.vo.SkYueDanOrderVo;
import org.dromara.app.service.*;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.params.AppTypeName;
import org.dromara.common.redis.utils.RedisUtils;
import org.dromara.system.domain.SysDictData;
import org.dromara.system.service.ISysConfigService;
import org.dromara.system.service.ISysDictDataService;
import org.dromara.web.CssUtil.CssOrderPaySever;
import org.dromara.web.CssUtil.WxPayBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Tag(name = "约单相关接口")
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/yuedan")
@SaIgnore
public class AppYueDanInterface {

    private final ISkYueDanOrderService iSkYueDanOrderService;

    private final ISysDictDataService iSysDictDataService;

    private final ISkDaRenApplyService iSkDaRenApplyService;

    private final ISkUserTrendsService iSkUserTrendsService;

    private final ISkFansUserService iSkFansUserService;

    private final ISkDongtaiPinglunService iSkDongtaiPinglunService;


    private final ISkAppUserService iSkAppUserService;

    private final ISysConfigService iSysConfigService;

    private final CssOrderPaySever cssOrderPaySever;

    private final ISkYueDanOrderLogService iSkYueDanOrderLogService;

    @Autowired
    WxPayBean wxPayBean;
    /**
     * 约玩项目类别
     *
     * @param req
     * @return
     */
    @PostMapping("/getProjectCategory")
    @Operation(summary = "约玩项目类别", method = "post")
    public R<List<AppTypeName>> getProjectCategory(HttpServletRequest req) {
        List<AppTypeName> list = iSysDictDataService.getListByType("yue_wan_project");
        return R.ok(list);
    }

    /**
     * 约玩达人价格
     *
     * @param req
     * @return
     */
    @PostMapping("/getDanRenPrice")
    @Operation(summary = "约玩达人价格", method = "post")
    public R<List<AppTypeName>> getDanRenPrice(HttpServletRequest req) {
        List<AppTypeName> list = iSysDictDataService.ferDanRenPrice("da_ren_price_");
        return R.ok(list);
    }


    /**
     * 预约下单价格计算
     */
    @PostMapping("/reservationOrderPrice")
    @Operation(summary = "预约下单价格计算", method = "post")
    public R<Map<String,BigDecimal>> reservationOrderPrice(@RequestBody AppTypeName params, HttpServletRequest req) {
        SysDictData sysDictData = iSysDictDataService.getInfo(params);
        BigDecimal zk = getZhekou(req);
        BigDecimal price = new BigDecimal(sysDictData.getDictValue()).multiply(zk);
        BigDecimal allPrice = new BigDecimal(sysDictData.getDictValue()).subtract(price);
        Map<String,BigDecimal> map = new HashMap<>();
        map.put("price",price.setScale(2, RoundingMode.HALF_UP));
        map.put("allPrice",allPrice);
        return R.ok(map);
    }


    public BigDecimal getZhekou(HttpServletRequest req){
        //判断用户是不是会员
        SkAppUser skAppUser = iSkAppUserService.getUserById(CssUtils.getUserId(req));
        Long vipType = 0L;
        if (skAppUser.getVipType().longValue()>=1){
            if (skAppUser.getVipTime()!=null && DateUtil.parse(skAppUser.getVipTime()+" 23:59:59", DatePattern.NORM_DATETIME_PATTERN).getTime()>=new Date().getTime()){
                vipType = skAppUser.getVipType();
            }
        }
        String zhekou = "10";
        if(vipType.longValue()==1){
            zhekou = iSysConfigService.selectConfigByKey(CssUtils.getHuiYuanConfig("白银下单享受折扣优惠").toString());
        }
        if(vipType.longValue()==2){
            zhekou = iSysConfigService.selectConfigByKey(CssUtils.getHuiYuanConfig("黄金下单享受折扣优惠").toString());
        }
        if(vipType.longValue()==3){
            zhekou = iSysConfigService.selectConfigByKey(CssUtils.getHuiYuanConfig("钻石下单享受折扣优惠").toString());
        }
        BigDecimal zk = new BigDecimal(zhekou).divide(BigDecimal.TEN);
        return  zk;
    }

    /**
     * 创建预约下单
     *
     * @param params
     * @param req
     * @return
     */
    @PostMapping("/createReservationOrder")
    @Operation(summary = "预约下单", method = "post")
    public R createReservationOrder(@RequestBody AppCreateYueDanParams params, HttpServletRequest req) {

            AppTypeName app = new AppTypeName();
            app.setDictName(params.getDarenTitle());
            app.setDictValue(params.getPrice()+"");
            app.setDictType(params.getPriceType());
            SysDictData sysDictData = iSysDictDataService.getInfo(app);
            BigDecimal zk = getZhekou(req);
            BigDecimal price = new BigDecimal(sysDictData.getDictValue()).multiply(zk);
            params.setZhekou(zk);
            params.setZhekouMoney(price.multiply(new BigDecimal(params.getLongTime())));
            SkYueDanOrder order =  iSkYueDanOrderService.createReservationOrder(params, req);
            //添加log
            iSkYueDanOrderLogService.createLog(order,"创建订单",1L);
            String json = "";
            System.out.println("order: "+order.getPayType().longValue());
        try {
            if (order.getPayType().longValue() == 1) {
                //微信支付
                json =  cssOrderPaySever.appYyPay(req,order);
            } else {
                //支付宝支付
            }
            System.out.println("json: "+json);
            return R.ok(JSONUtil.parse(json));
        }catch (RuntimeException e){
            throw new RuntimeException("创建失败");
        }

    }

    /**
     * 达人订单
     *
     * @param params
     * @param req
     * @return
     */
    @PostMapping("/daRenOrdersList")
    @Operation(summary = "达人订单", method = "post")
    public R<List<AppOrderInfo>> orderOrdersList(@RequestBody AppYueDanParams params, HttpServletRequest req) {
        List<AppOrderInfo> list = iSkYueDanOrderService.pendingOrders(params, req);
        return R.ok(list);
    }

    /**
     * 我的达人订单
     *
     * @param params
     * @param req
     * @return
     */
    @PostMapping("/myOrdersList")
    @Operation(summary = "我的达人订单", method = "post")
    public R<List<AppOrderInfo>> myOrdersList(@RequestBody AppYueDanParams params, HttpServletRequest req) {
        List<AppOrderInfo> list = iSkYueDanOrderService.myOrdersList(params, req);
        return R.ok(list);
    }

    /**
     * 支付成功回调
     * @param req
     * @return
     */
    @PostMapping("/paymentCallback")
    @Operation(summary = "支付成功回调", method = "post")
    public String paymentCallback(HttpServletRequest req) {
        try {
            Map<String,String> map = cssOrderPaySever.callback(req);
            System.out.println("支付成功回调:"+map);
            WxPayApiConfig wxPayApiConfig = getApiConfig();
            WxPayApiConfigKit.putApiConfig(wxPayApiConfig);
            String returnCode = map.get("return_code");
            boolean verifyNotify = WxPayKit.verifyNotify(map, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey(), SignType.HMACSHA256);
            System.out.println("verifyNotify:"+verifyNotify);
            if (verifyNotify) {
                System.out.println("returnCode:"+returnCode);
                boolean flag = WxPayKit.codeIsOk(returnCode);
                System.out.println("WxPayKit.codeIsOk(returnCode):"+flag);
                if (flag) {
                    // 从Map中获取具体参数进行业务处理
                    iSkYueDanOrderService.getPaymentCallback(map);
                }
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return "fail";
    }

    //组装数据
    public WxPayApiConfig getApiConfig(){
        WxPayApiConfig apiConfig;

        try {
            apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
        } catch (Exception e) {
            apiConfig = WxPayApiConfig.builder()
                .appId(wxPayBean.getAppId())
                .mchId(wxPayBean.getMchId())
                .partnerKey(wxPayBean.getPartnerKey())
                .certPath(wxPayBean.getCertPath())
                .domain(wxPayBean.getDomain())
                .build();
        }
        return apiConfig;
    }
    /**
     * 甄选搭子列表
     */
    @PostMapping("/getSelectionSubItemsList")
    @Operation(summary = "甄选搭子列表", method = "post")
    public R<List<AppDaRenInfo>> getSelectionSubItemsList(@RequestBody AppPageParams params, HttpServletRequest req) {
        List<AppDaRenInfo> list = iSkDaRenApplyService.getSelectionSubItemsList(params,req);
        return R.ok(list);
    }


    /**
     * 发布动态
     */
    @PostMapping("/publishUpdates")
    @Operation(summary = "发布动态", method = "post")
    public R publishUpdates(@RequestBody AppPublicUpdatesParams params, HttpServletRequest req) {
        iSkUserTrendsService.publishUpdates(params,req);
        return R.ok("发布成功");
    }


    /**
     * 动态列表
     */
    @PostMapping("/getTrendsList")
    @Operation(summary = "动态列表", method = "post")
    public R<List<AppTrendsReturn>> getTrendsList(@RequestBody AppPageParams params, HttpServletRequest req) {
        List<AppTrendsReturn> list = iSkUserTrendsService.getTrendsList(params,req);
        return R.ok(list);
    }

    /**
     * 动态详情
     */
    @PostMapping("/getTrendsInfo")
    @Operation(summary = "动态详情", method = "post")
    public R<AppTrendsReturn> getTrendsInfo(@RequestBody AppDetailByIdParams params, HttpServletRequest req) {
        AppTrendsReturn app = iSkUserTrendsService.getTrendsInfo(params,req);
        return R.ok(app);
    }

    /**
     * 评论动态
     */
    @PostMapping("/commentYueJu")
    @Operation(summary = "评论动态", method = "post")
    public R commentYueJu(@RequestBody AppPlingLunParams params, HttpServletRequest req) {
        iSkDongtaiPinglunService.commentYueJu(params,req);
        return R.ok("评论成功");
    }

    /**
     * 动态评论列表
     */
    @PostMapping("/getCommentYueJuList")
    @Operation(summary = "动态评论列表", method = "post")
    public R getCommentYueJuList(@RequestBody AppPingLunpageParams params, HttpServletRequest req) {
        List<AppYueJuPingLunReturn> list = iSkDongtaiPinglunService.getCommentYueJuList(params,req);
        return R.ok(list);
    }

    /**
     * 点赞动态
     */
    @PostMapping("/dongtaiLikes")
    @Operation(summary = "点赞动态", method = "post")
    public R dongtaiLikes(@RequestBody AppDetailByIdParams params, HttpServletRequest req) {
        iSkDongtaiPinglunService.dongtaiLikes(params,req);
        return R.ok("操作成功");
    }

    /**
     * 用户自己发布的动态
     */
    @PostMapping("/getMyDongTaiList")
    @Operation(summary = "用户自己发布的动态", method = "post")
    public R<List<AppTrendsReturn>> getMyDongTaiList(@RequestBody AppPingLunpageParams params, HttpServletRequest req) {
        List<AppTrendsReturn> list = iSkUserTrendsService.getMyDongTaiList(params,req);
        return R.ok(list);
    }


    /**
     * 关注用户
     */
    @PostMapping("/getLike")
    @Operation(summary = "关注用户", method = "post")
    public R<List<AppTrendsReturn>> getLike(@RequestBody AppDetailByIdParams params, HttpServletRequest req) {
        iSkFansUserService.getLike(params,req);
        return R.ok("操作成功");
    }
    /**
     * 关注用户列表
     */
    @PostMapping("/getLikeList")
    @Operation(summary = "关注用户列表", method = "post")
    public R<List<AppDaRenInfo>> getLikeList(@RequestBody AppPageParams params, HttpServletRequest req) {
        List<AppDaRenInfo> list = iSkFansUserService.getLikeList(params,req);
        return R.ok(list);
    }

    /**
     * 下单用户 取消订单
     */
    @PostMapping("/cencelOrder")
    @Operation(summary = "取消订单", method = "post")
    public R cencelOrder(@RequestBody AppDetailByIdParams params, HttpServletRequest req) {
        //判断是否已接单
//        SkYueDanOrderVo order = iSkYueDanOrderService.queryById(params.getId());
//        if (order.getPayState().longValue()==1){
//            cssOrderPaySever.refund(order.getPayOrder(),"YY-"+order.getId());
//        }
        SkYueDanOrder order = iSkYueDanOrderService.cencelUserOrder(params,req);
        if (order==null){
            return R.fail("该订单状态无法取消");
        }
        cssOrderPaySever.refund(order);
        return R.ok("取消成功");
    }

    /**
     * 达人接单
     */
    @PostMapping("/getReceivinOrders")
    @Operation(summary = "达人接单", method = "post")
    public R getReceivinOrders(@RequestBody AppDetailByIdParams params, HttpServletRequest req) {
        iSkYueDanOrderService.getReceivinOrders(params,req);
        return R.ok("接单成功");
    }

    /**
     * 达人开始服务
     */
    @PostMapping("/getStartService")
    @Operation(summary = "达人开始服务", method = "post")
    public R getStartService(@RequestBody AppDetailByIdParams params, HttpServletRequest req) {
        SkYueDanOrder order = iSkYueDanOrderService.getStartService(params,req);
        //添加缓存
        LocalDateTime start = LocalDateTime.parse(order.getStartFwTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime end = LocalDateTime.parse(order.getEndFwTime(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Duration duration = Duration.between(start, end);
        RedisUtils.setCacheObject(RedisServiceUtils.getYueDanOrder()+":"+order.getId(),order.getId(), duration);
        return R.ok("服务成功");
    }


    /**
     * 达人转单
     */
    @PostMapping("/getTransferOrder")
    @Operation(summary = "达人转单", method = "post")
    public R getTransferOrder(@RequestBody AppDetailByIdParams params, HttpServletRequest req) {
        iSkYueDanOrderService.getTransferOrder(params,req);
        return R.ok("转单成功");
    }


    /**
     * 消息列表
     */
    @PostMapping("/getMessageList")
    @Operation(summary = "消息列表", method = "post")
    public R<List<AppDaRenInfo>> getMessageList(@RequestBody AppMessageParams params, HttpServletRequest req) {
        List<AppDaRenInfo> list = iSkYueDanOrderService.getMessageList(params,req);
        return R.ok(list);
    }

    /**
     * 浏览历史20条数据
     */
    @PostMapping("/getBrowsingHistory")
    @Operation(summary = "浏览历史20条数据", method = "post")
    public R<List<AppDaRenInfo>> getBrowsingHistory( HttpServletRequest req) {
        List<AppDaRenInfo> list = iSkYueDanOrderService.getBrowsingHistory(req);
        return R.ok(list);
    }

    /**
     * 我的粉丝列表
     */
    @PostMapping("/getFansList")
    @Operation(summary = "我的粉丝列表", method = "post")
    public R<List<AppDaRenInfo>> getFansList(@RequestBody AppPageParams params, HttpServletRequest req) {
        List<AppDaRenInfo> list = iSkFansUserService.getFansList(params,req);
        return R.ok(list);
    }


}
